package com.yiren.backstage.judge.services.standard.impl;

import android.content.Context;

import com.yiren.backstage.config.api.LoadConfigApi;
import com.yiren.backstage.currency.bean.CarStateBean;
import com.yiren.backstage.currency.enums.CarStateValueEnum;
import com.yiren.backstage.currency.enums.TaskStateEnum;
import com.yiren.backstage.judge.NumberConstant;
import com.yiren.backstage.judge.api.impl.ExamJudgeApiImpl;
import com.yiren.backstage.judge.services.standard.IPackageStateService;
import com.yiren.backstage.judge.thread.AutoJudgeThread;

/**
 * Time:2022/3/31 10:29
 * Author:xiaozan
 * Description:封装状态服务实现
 */
public class PackageStateServiceImpl implements IPackageStateService {

    private Context context;
    private CarStateBean carStateBean;

    /**
     * 角度状态：角度值范围：0-360
     * 0：正常偏转未过360度交叉点
     * 1：顺时针（右转：值越来越小（不过交叉点时））旋转过360度交叉点 ：
     * 2：逆时针（左转：值越来越大（不过交叉点时））旋转过360度交叉点
     */
    private int angleState = 0;
    private float lastAngle = 0;      //上次角度
    private int startBrakeSpeed = 0;  //开始刹车的速度
    private long startBrakeTime = 0;  //开始刹车的时间
    private int currentGear = 0;      //当前档位
    private long lastCdTime;          //上次闯动时间
    private float lastRotateSpeed;    //上一次转速
    private float lastPitchAngle;     //上一次俯仰角
    private int deflectionDistance;   //偏转距离
    private int startDistance = 9999; //开始距离边线距离
    private boolean startEngine;      //是否启动发动机

    public PackageStateServiceImpl(Context context) {
        this.context = context;
        carStateBean = CarStateBean.getInstance();
    }

    @Override
    public CarStateValueEnum flameout() {
        //上车准备执行时不评判熄火
        if (null != ExamJudgeApiImpl.projectStateMap.get(40100) && ExamJudgeApiImpl.projectStateMap.get(40100).getTaskState() == TaskStateEnum.IN_PROCESS)
            return CarStateValueEnum.NO_PASS;

        //1，先启动发动机
        if (!startEngine) {
            if (carStateBean.getRotateSpeed() > 200) startEngine = true;
            return CarStateValueEnum.NO_PASS;
        }

        //2，判断是否熄火 靠边停车执行时拉手刹前才评判熄火
        if (carStateBean.getRotateSpeed() < 200) {
            if (null != ExamJudgeApiImpl.projectStateMap.get(40600) && ExamJudgeApiImpl.projectStateMap.get(40600).getTaskState() == TaskStateEnum.IN_PROCESS) {
                if (carStateBean.getParkingBrake() == CarStateValueEnum.COCKING) {
                    return CarStateValueEnum.NO_PASS;
                }
            }
            return CarStateValueEnum.PASS;
        }
        return CarStateValueEnum.NO_PASS;
    }

    @Override
    public float deflectionAngle(float startAngle, float realTimeAngle, int checkType) {
        float deflectionAngle = 0;
        if (lastAngle == 0) lastAngle = realTimeAngle;
        //判断上次角度对比实时角度，如果角度差大于180度，那么就是遇到360度交叉点
        if (Math.abs((realTimeAngle - lastAngle)) > 180) {
            if (realTimeAngle - lastAngle > 0) {  //实时角度大于上次角度
                angleState = angleState == 2 ? 0 : 1;
            } else {  //实时角度小于上次角度
                angleState = angleState == 1 ? 0 : 2;
            }
        }
        switch (angleState) {
            case 0:
                switch (checkType) {
                    case 1:
                        deflectionAngle = Math.abs(realTimeAngle - startAngle);
                        break;
                    case 2:
                        deflectionAngle = realTimeAngle - startAngle;
                        break;
                    case 3:
                        deflectionAngle = startAngle - realTimeAngle;
                        break;
                }
                break;
            case 1:
                switch (checkType) {
                    case 1:
                        deflectionAngle = startAngle + (360 - realTimeAngle);
                        break;
                    case 2:
                        deflectionAngle = -startAngle - (360 - realTimeAngle);
                        break;
                    case 3:
                        deflectionAngle = startAngle + (360 - realTimeAngle);
                        break;
                }
                break;
            case 2:
                switch (checkType) {
                    case 1:
                        deflectionAngle = realTimeAngle + (360 - startAngle);
                        break;
                    case 2:
                        deflectionAngle = realTimeAngle + (360 - startAngle);
                        break;
                    case 3:
                        deflectionAngle = -realTimeAngle - (360 - startAngle);
                        break;
                }
                break;

        }
        lastAngle = realTimeAngle;
        return deflectionAngle;
    }

    @Override
    public float deflectionDistance(int startDistance, int realTimeDistance) {
        //开始距离检测不到时先等到检测距离
        if (this.startDistance == 9999) {
            if (startDistance != 9999) {
                this.startDistance = startDistance;
            } else {
                if (realTimeDistance != 9999) this.startDistance = realTimeDistance;
            }
        }

        //检测不到线时不检测
        if (realTimeDistance != 9999) {
            deflectionDistance = Math.abs(realTimeDistance - this.startDistance);
        }
        return deflectionDistance;
    }

    @Override
    public CarStateValueEnum judgeExecuteFinish(AutoJudgeThread autoJudgeThread) {
        AutoJudgeThread mRootTask = autoJudgeThread.getmRootTask();
        if (mRootTask.getmExecutedNodeCount() >= mRootTask.getSumNodeCount() - 1) {
            return CarStateValueEnum.PASS;
        }
        return CarStateValueEnum.NO_PASS;
    }

    @Override
    public CarStateValueEnum brakeNoStableCheck() {
        if (carStateBean.getFootBrake() == CarStateValueEnum.STEP_ON) {
            if (startBrakeSpeed == 0) {
                startBrakeSpeed = (int) carStateBean.getSpeed();
                startBrakeTime = System.currentTimeMillis();
            }
            int deltaSpeed = Math.abs(startBrakeSpeed - (int) carStateBean.getSpeed());
            float deltaTime = (System.currentTimeMillis() - startBrakeTime) / 1000.0f;
            if (deltaTime != 0) {
                //如果速度下降大于10m/s,则制动不平顺
                if ((deltaSpeed / deltaTime) > NumberConstant.BRAKE_NO_STABLE * LoadConfigApi.loadPracticeCarCheckConfig(context).getZdbpsValue()) {
                    return CarStateValueEnum.PASS;
                }
            }
        } else {
            startBrakeSpeed = 0;
            startBrakeTime = 0;
            return CarStateValueEnum.NO_PASS;
        }
        return CarStateValueEnum.NO_PASS;
    }

    @Override
    public CarStateValueEnum bypassGearCheck() {
        switch (LoadConfigApi.loadSignalSourceConfig(context).getCarType()) {
            case C2_MODEL:
                //自动挡不检测
                return CarStateValueEnum.NO_PASS;
            default:
                if (carStateBean.getSeparationReunion() == CarStateValueEnum.STEP_ON) {
                    currentGear = carStateBean.getGear().getValue();
                    return CarStateValueEnum.NO_PASS;
                } else {
                    int deltaGear = carStateBean.getGear().getValue() - currentGear;
                    if (deltaGear > 1) {
                        return CarStateValueEnum.PASS;
                    }
                }
                break;
        }
        return CarStateValueEnum.NO_PASS;
    }

    @Override
    public CarStateValueEnum qibuThroughDynamic() {
        switch (LoadConfigApi.loadSignalSourceConfig(context).getCarType()) {
            case C2_MODEL:
                return CarStateValueEnum.NO_PASS;
            default:
                if (carStateBean.getSpeed() > 10) {
                    lastCdTime = 0;
                } else {
                    if (lastCdTime == 0) {
                        lastCdTime = System.currentTimeMillis();
                        lastRotateSpeed = carStateBean.getRotateSpeed();
                        lastPitchAngle = carStateBean.getPitchAngle();
                    }
                    long currentTime = System.currentTimeMillis();
                    float currentRotateSpeed = carStateBean.getRotateSpeed();
                    float currentPitchAngle = carStateBean.getPitchAngle();
                    float currentCostTime = (float) ((currentTime - lastCdTime) / 1000.0);
                    if (currentCostTime != 0) {
                        //转速变化速率（转每秒）
                        float rateRotateSpeed = Math.abs(currentRotateSpeed - lastRotateSpeed) / currentCostTime;
                        //俯仰角变化速率（度每秒）
                        float ratePithAngle = Math.abs(currentPitchAngle - lastPitchAngle) / currentCostTime;
                        if (rateRotateSpeed > NumberConstant.QIBU_DYNAMIC_ROTATE * LoadConfigApi.loadPracticeCarCheckConfig(context).getQbcdValue() && ratePithAngle > NumberConstant.QIBU_DYNAMIC_PITCH_ANGLE * LoadConfigApi.loadPracticeCarCheckConfig(context).getQbcdValue()) {
                            return CarStateValueEnum.PASS;
                        }
                        lastRotateSpeed = currentRotateSpeed;
                        lastPitchAngle = currentPitchAngle;
                        lastCdTime = currentTime;
                    }
                }
                break;
        }
        return CarStateValueEnum.NO_PASS;
    }
}
